package edu.gtcfla.km.repositories.page;

import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.vsg.common.page.CriteriaQueryConverterMap;
import org.vsg.common.page.PaginationKeyword;
import org.vsg.common.page.datatrans.DataTransformer;
import org.vsg.common.page.hiberante4.HibernatePageProcessor;
import org.vsg.common.page.processor.PaginationProcessorException;

import edu.gtcfla.km.model.KnowledgeD;
import edu.gtcfla.km.model.LogsD;
import edu.gtcfla.km.model.UserGroupD;



/**
 * @author Bill Vison
 *
 */
public class AvialableLogsProc extends HibernatePageProcessor {



	private static final Logger logger = LoggerFactory.getLogger(AvialableLogsProc.class);	
	
	
	private Set<String> cateIds;
	

	public Set<String> getCateIds() {
		return cateIds;
	}


	public void setCateIds(Set<String> cateIds) {
		this.cateIds = cateIds;
	}


	/* (non-Javadoc)
	 * @see org.vsg.commons.util.pagination.processor.PaginationProcessor#getPaginationList(org.vsg.commons.util.pagination.datatrans.DataTransformer)
	 */
	@SuppressWarnings("rawtypes")
	public List getPageList(DataTransformer transformer)
			throws PaginationProcessorException {
		// TODO Auto-generated method stub
		List dataList = new Vector();


		int offset = (Integer)transformer.getImplicitValue(PaginationKeyword.TFS_DATA_OFFSET);
		int rows = (Integer)transformer.getImplicitValue(PaginationKeyword.TFS_ROWS);
	
		StringBuffer query = new StringBuffer("select ");
		query.append("ug.id , ug.date , ug.userid , ug.name , ug.typename , ug.type ");
		query.append("from ").append(LogsD.class.getName() );
		query.append(" as ug ");
		//query.append("left join knowledge.categoryD as cate ");
		
		
		// -------------- get the condition for the query 
		WhereQueryConverterMap queryConverter = new WhereQueryConverterMap(transformer);
		String subQuery = queryConverter.parseToString();
		
		if (subQuery.length() > 0) {
			query.append("where ");
			query.append(subQuery);
		}

		
		if (logger.isInfoEnabled()) {
			logger.info("Execute SQL :"+query.toString());
		}
		

		
		Session sess = this.getSession();
		
		try {
			Query hql = sess.createQuery( query.toString() );
			for (Map.Entry<String, java.io.Serializable> paraItem : queryConverter.getParameterMap().entrySet() ) {
				hql.setParameter(paraItem.getKey(), paraItem.getValue() );
			}
			hql.setFirstResult(offset);
			hql.setMaxResults(rows);			
			
			Iterator dataIter = (Iterator)hql.iterate();
			
			Object[] fields = null;
			while (dataIter.hasNext()) {
				fields = (Object[])dataIter.next();
				
				int i = 0;
				LogsD ugd = new LogsD();
				ugd.setId( (String)fields[i++] );
				ugd.setDate((String)fields[i++]);
				ugd.setUserid( (String)fields[i++]  );
				ugd.setName( (String)fields[i++]  );
				ugd.setTypename( (String)fields[i++]  );
				ugd.setType( (String)fields[i++] );
				dataList.add( ugd );	
			}
			
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return dataList;
	}


	/* (non-Javadoc)
	 * @see org.vsg.commons.util.pagination.processor.PaginationProcessor#getTotalRecords(org.vsg.commons.util.pagination.datatrans.DataTransformer)
	 */
	public int getTotalRecords(DataTransformer transformer)
			throws PaginationProcessorException {
		// TODO Auto-generated method stub
		int totalRecord = 0;
		
		StringBuffer query = new StringBuffer("SELECT ");
		query.append("count(*) ");
		query.append("FROM ").append(LogsD.class.getName());
		query.append(" as ug ");
		
		// -------------- get the condition for the query 
		WhereQueryConverterMap queryConverter = new WhereQueryConverterMap(transformer);
		String subQuery = queryConverter.parseToString();
		
		if (subQuery.length() > 0) {
			query.append("where ");
			query.append(subQuery);
		}

		if (logger.isInfoEnabled()) {
			logger.info("Execute SQL :"+query.toString());
		}
		
		
		Session sess = this.getSession();
		Query hql = sess.createQuery( query.toString() );
		for (Map.Entry<String, java.io.Serializable> paraItem : queryConverter.getParameterMap().entrySet() ) {
			hql.setParameter(paraItem.getKey(), paraItem.getValue() );
		}

		Iterator iter = hql.iterate();			
		while (iter.hasNext()) {
			totalRecord = new Integer(iter.next().toString());
		}
		
		return totalRecord;
	}
	
	
	private class WhereQueryConverterMap implements CriteriaQueryConverterMap {
		
		private DataTransformer transformer;
		
		private Map<String, java.io.Serializable> paramMap = new LinkedHashMap<String , java.io.Serializable>();
		
		WhereQueryConverterMap(DataTransformer transformer) {
			this.transformer = transformer;
		}
		

		@Override
		public String parseToString() {
			
			StringBuilder query = new StringBuilder();
			
			String queryString = (String)transformer.getValue("query");
			if (queryString != null && !queryString.equals("")) {
				query.append("ug.groupName like :query ");

				paramMap.put("query", "%" + queryString + "%");
			}
			
			return query.toString();
		}

		
		
		@Override
		public String toSort() {
			Sort sort = (Sort)transformer.getImplicitValue(PaginationKeyword.TFS_SORT);
			
			StringBuilder sortPart = new StringBuilder();
			
			if (sort == null) {
				return sortPart.toString();
			}
			
			Iterator<Order> orderIter  = sort.iterator();
			while (orderIter.hasNext()) {
				Order ord = orderIter.next();
				
				if (sortPart.length() > 0) {
					sortPart.append(", ");
				}
				
				if (ord.getProperty().equalsIgnoreCase("groupName")) {
					sortPart.append("ug.groupName "+ord.getDirection()+" ");
				}
			}
			return sortPart.toString();
		}


		@Override
		public Map<String, java.io.Serializable> getParameterMap() {
			return paramMap;
		}

		
		
	}

}